

package com.sixfoot.adminsys.frames.rolePerm;

import com.sixfoot.adminsys.DemoProperties;
import com.sixfoot.adminsys.utilities.UIUtils;
import com.sixfoot.domain.Permission;
import com.sixfoot.facade.permission.PermissionDto;
import com.sixfoot.facade.role.RoleDto;
import com.sixfoot.facade.role.RoleInputArgs;
import com.sixfoot.service.PermissionService;
import com.sixfoot.service.RoleService;
import org.dozer.DozerBeanMapper;
import org.dozer.Mapper;
import org.jb2011.lnf.beautyeye.ch3_button.BEButtonUI;

import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.*;
import java.util.List;


@DemoProperties(
        value = "角色权限",
        category = "权限管理",
        description = "进入可以设置角色权限"
)
public class RolePerm extends JPanel {

    private static final Dimension VGAP10 = new Dimension(1, 10);

    private RoleService roleService = (RoleService) UIUtils.getBean("roleService");
    private PermissionService permissionService = (PermissionService) UIUtils.getBean("permissionService");

    private JList roleList; // 角色JLIST
    private JList selectList; // 未拥有权限JLIST
    private JList selectedList; // 已拥有权限JLIST
    private JButton addPermBtn;
    private JButton removePermBtn;
    private final ActionListener addPermActionListener = new AddPermActionListener();
    private final ActionListener removePermActionListener = new RemovePermActionListener();
    private DefaultListModel<PermissionDto> roleNoHasPerms = new DefaultListModel<>(); // 当前角色没有的权限
    private DefaultListModel<PermissionDto> roleHasPerms = new DefaultListModel<>(); // 当前角色已有的权限
    private DefaultListModel<RoleDto> roleModalList = new DefaultListModel<RoleDto>(); // 当前角色

    public static void main(String[] args) {
        JFrame frame = new JFrame(RolePerm.class.getAnnotation(DemoProperties.class).value());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(new RolePerm());
        frame.setPreferredSize(new Dimension(800, 600));
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public RolePerm() {
        List<RoleDto> roles = getRoles();
        roleModalList = new DefaultListModel<RoleDto>();
        for (RoleDto r : roles) {
            roleModalList.addElement(r);
        }
        setLayout(new BorderLayout());
        JPanel btnPanel = new JPanel();
        JButton addRoleBtn = new JButton("添加角色");
        addRoleBtn.addActionListener(new AddRoleListener());
        JButton editRoleBtn = new JButton("编辑角色");
        editRoleBtn.addActionListener(new EditRoleListener());
        JButton deleteRoleBtn = new JButton("删除角色");
        deleteRoleBtn.addActionListener(new DeleteRoleListener());
        deleteRoleBtn.setUI(new BEButtonUI().setNormalColor(BEButtonUI.NormalColor.red));
        btnPanel.add(addRoleBtn);
        btnPanel.add(editRoleBtn);
        btnPanel.add(deleteRoleBtn);
        add(btnPanel, BorderLayout.NORTH);
        JPanel centerPanel = new JPanel();
        centerPanel.setLayout(new BoxLayout(centerPanel, BoxLayout.X_AXIS));
        add(centerPanel, BorderLayout.CENTER);

        JPanel rolePanel = new JPanel();
        rolePanel.setLayout(new BoxLayout(rolePanel, BoxLayout.Y_AXIS));
        rolePanel.add(Box.createRigidArea(VGAP10));
        rolePanel.add(new JLabel("角色"));
        rolePanel.add(Box.createRigidArea(VGAP10));
        roleList = new JList(roleModalList);
        roleList.setSize(300,300);
        roleList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        JScrollPane roleScrollPane = new JScrollPane(roleList);
        rolePanel.add(roleScrollPane);

        JPanel selectPanel = new JPanel();
        selectPanel.setLayout(new BoxLayout(selectPanel, BoxLayout.Y_AXIS));
        selectPanel.add(Box.createRigidArea(VGAP10));
        selectPanel.add(new JLabel("未拥有权限"));
        selectPanel.add(Box.createRigidArea(VGAP10));
        selectList = new JList();
        JScrollPane selectScrollPane = new JScrollPane(selectList);
        selectPanel.add(selectScrollPane);

        JPanel selectedPanel = new JPanel();
        selectedPanel.setLayout(new BoxLayout(selectedPanel, BoxLayout.Y_AXIS));
        selectedPanel.add(Box.createRigidArea(VGAP10));
        selectedPanel.add(new JLabel("已拥有权限"));
        selectedPanel.add(Box.createRigidArea(VGAP10));
        selectedList = new JList();
        JScrollPane selectedScrollPane = new JScrollPane(selectedList);
        selectedPanel.add(selectedScrollPane);

        addPermBtn = new JButton(">>");
        addPermBtn.addActionListener(addPermActionListener);
        removePermBtn = new JButton("<<");
        removePermBtn.addActionListener(removePermActionListener);
        JPanel buttonPanel = new JPanel();
        buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.Y_AXIS ));
        buttonPanel.add(addPermBtn);
        buttonPanel.add(Box.createRigidArea (new Dimension(1, 15)));
        buttonPanel.add(removePermBtn);
        buttonPanel.setAlignmentY(java.awt.Component.TOP_ALIGNMENT );
        buttonPanel.setBorder(BorderFactory.createEmptyBorder (15, 5, 15, 5));
        centerPanel.add(Box.createRigidArea (new Dimension(15, 15)));
        centerPanel.add(rolePanel);
        centerPanel.add(Box.createRigidArea (new Dimension(100, 100)));
        centerPanel.add(selectPanel);
        centerPanel.add(buttonPanel);
        centerPanel.add(selectedPanel);
        centerPanel.add(Box.createRigidArea (new Dimension(15, 15)));

        roleList.addListSelectionListener(lsl);
        roleList.setSelectedIndex(0);
    }

    public List<RoleDto> getRoles() {
        List<RoleDto> roles = roleService.findAll();
        return roles;
    }

    // 角色选择监听
    private ListSelectionListener lsl = new ListSelectionListener() {
        public void valueChanged(ListSelectionEvent e) {
            if (e.getValueIsAdjusting()) {
                return;
            }
            RoleDto r = getSelectedRole();
            if (r == null) {
                return;
            }
            Set<Permission> rolePermSet = r.getPerms();
            List<String> roleHasPermIds = new ArrayList<>();
            if (rolePermSet != null) {
                Iterator<Permission> iterator = rolePermSet.iterator();
                while (iterator.hasNext()) {
                    roleHasPermIds.add(iterator.next().getId());
                }
            }
            List<PermissionDto> allPerms = permissionService.findAll();
            roleNoHasPerms = new DefaultListModel<>();
            roleHasPerms = new DefaultListModel<>();
            for (PermissionDto p : allPerms) {
                if (roleHasPermIds.contains(p.getId()) == false) {
                    roleNoHasPerms.addElement(p);
                } else {
                    roleHasPerms.addElement(p);
                }
            }
            selectList.setModel(roleNoHasPerms);
            selectedList.setModel(roleHasPerms);
        }
    };

    // 监听增加权限按钮点击
    private class AddPermActionListener implements ActionListener {
        public void actionPerformed(ActionEvent event) {
            Mapper mapper = new DozerBeanMapper();

            List<PermissionDto> selectedAddPerms = getSelectedAddPerms();
            for (PermissionDto p : selectedAddPerms) {
                roleNoHasPerms.removeElement(p);
                roleHasPerms.addElement(p);
            }
            List<PermissionDto> roleHasPerms = getRoleHasPerms();
            RoleDto selectedRole = getSelectedRole();
            List<String> permIds = new ArrayList<>();
            Set<Permission> roleSet = new HashSet<>();
            for (PermissionDto p : roleHasPerms) {
                permIds.add(p.getId());
                roleSet.add(mapper.map(p, Permission.class));
            }
            RoleInputArgs roleInputArgs = new RoleInputArgs();
            roleInputArgs.setId(selectedRole.getId());
            roleInputArgs.setPermIds(permIds);
            roleInputArgs.setCode(selectedRole.getCode());
            roleInputArgs.setDescription(selectedRole.getDescription());
            roleInputArgs.setName(selectedRole.getName());
            roleService.update(roleInputArgs);
            selectedRole.setPerms(roleSet);
        }
    }

    // 监听移除权限按钮点击
    private class RemovePermActionListener implements ActionListener {
        public void actionPerformed(ActionEvent event) {
            Mapper mapper = new DozerBeanMapper();

            List<PermissionDto> selectedRemovePerms = getSelectedRemovePerms();
            for (PermissionDto p : selectedRemovePerms) {
                roleHasPerms.removeElement(p);
                roleNoHasPerms.addElement(p);
            }

            List<PermissionDto> roleHasPerms = getRoleHasPerms();
            RoleDto selectedRole = getSelectedRole();
            List<String> permIds = new ArrayList<>();
            Set<Permission> roleSet = new HashSet<>();
            for (PermissionDto p : roleHasPerms) {
                permIds.add(p.getId());
                roleSet.add(mapper.map(p, Permission.class));
            }
            RoleInputArgs roleInputArgs = new RoleInputArgs();
            roleInputArgs.setId(selectedRole.getId());
            roleInputArgs.setPermIds(permIds);
            roleInputArgs.setCode(selectedRole.getCode());
            roleInputArgs.setDescription(selectedRole.getDescription());
            roleInputArgs.setName(selectedRole.getName());
            roleService.update(roleInputArgs);
            selectedRole.setPerms(roleSet);
        }
    }

    // 获取当前被选中的角色
    private RoleDto getSelectedRole() {
        return (RoleDto) roleList.getSelectedValue();
    }

    // 获取想要增加的权限
    private List<PermissionDto> getSelectedAddPerms() {
        return selectList.getSelectedValuesList();
    }

    // 获取想要增加的权限
    private List<PermissionDto> getSelectedRemovePerms() {
        return selectedList.getSelectedValuesList();
    }

    // 获取角色当前拥有的权限集合
    private List<PermissionDto> getRoleHasPerms() {
        List<PermissionDto> roleHasPerms = new ArrayList<>();
        ListModel model = selectedList.getModel();
        for (int i = 0; i < model.getSize(); i++) {
            roleHasPerms.add((PermissionDto) model.getElementAt(i));
        }
        return roleHasPerms;
    }

    // 监听添加角色按钮点击
    private class AddRoleListener implements ActionListener {
        public void actionPerformed(ActionEvent event) {
            Object[] message = new Object[10];
            JLabel nameLabel = new JLabel("角色名（必填）");
            JLabel codeLabel = new JLabel("code");
            JLabel desLabel = new JLabel("描述");
            JTextField name = new JTextField();
            JTextField code = new JTextField();
            JTextField desc = new JTextField();
            message[0] = nameLabel;
            message[1] = name;
            message[2] = codeLabel;
            message[3] = code;
            message[4] = desLabel;
            message[5] = desc;
            String[] options = {"确定"};
            int result = JOptionPane.showOptionDialog(
                    RolePerm.this,                        // the parent that the dialog blocks
                    message,                                    // the dialog message array
                    "添加角色", // the title of the dialog window
                    JOptionPane.DEFAULT_OPTION,                 // option type
                    JOptionPane.PLAIN_MESSAGE,            // message type
                    null,                                       // optional icon, use null to use the default icon
                    options,                                    // options string array, will be made into buttons
                    options[0]                                  // option that should be made into a default button
            );
            if (result == 0) {
                if (name.getText() == null || name.getText().trim().length() == 0) {
                    UIUtils.showWarning("请填写角色名！");
                    return;
                }

                RoleInputArgs roleInputArgs = new RoleInputArgs();
                roleInputArgs.setName(name.getText());
                roleInputArgs.setCode(code.getText());
                roleInputArgs.setDescription(desc.getText());
                RoleDto dbRole = roleService.add(roleInputArgs);

                RoleDto newRole = new RoleDto();
                newRole.setId(dbRole.getId());
                newRole.setName(name.getText());
                newRole.setCode(code.getText());
                newRole.setDescription(desc.getText());
                roleModalList.addElement(newRole);
            }

        }
    }

    // 监听删除角色按钮点击
    private class DeleteRoleListener implements ActionListener {
        public void actionPerformed(ActionEvent event) {
            RoleDto role = (RoleDto) roleList.getSelectedValue();
            if (role == null) {
                UIUtils.showWarning("请选择要删除的角色！");
                return;
            }
            int result = JOptionPane.showConfirmDialog(RolePerm.this, "确定要删除此角色吗？", "删除角色", JOptionPane.WARNING_MESSAGE);
            if (result == JOptionPane.YES_OPTION) {
                roleModalList.removeElement(role);
                roleService.delete(role.getId());
            } else if (result == JOptionPane.NO_OPTION) {

            }

        }
    }

    // 监听编辑角色按钮点击
    private class EditRoleListener implements ActionListener {
        public void actionPerformed(ActionEvent event) {
            RoleDto role = (RoleDto) roleList.getSelectedValue();

            Object[] message = new Object[10];
            JLabel nameLabel = new JLabel("角色名（必填）");
            JLabel codeLabel = new JLabel("code");
            JLabel desLabel = new JLabel("描述");
            JTextField name = new JTextField(role.getName());
            JTextField code = new JTextField(role.getCode());
            JTextField desc = new JTextField(role.getDescription());
            message[0] = nameLabel;
            message[1] = name;
            message[2] = codeLabel;
            message[3] = code;
            message[4] = desLabel;
            message[5] = desc;
            String[] options = {"确定"};
            int result = JOptionPane.showOptionDialog(
                    RolePerm.this,                        // the parent that the dialog blocks
                    message,                                    // the dialog message array
                    "编辑角色", // the title of the dialog window
                    JOptionPane.DEFAULT_OPTION,                 // option type
                    JOptionPane.PLAIN_MESSAGE,            // message type
                    null,                                       // optional icon, use null to use the default icon
                    options,                                    // options string array, will be made into buttons
                    options[0]                                  // option that should be made into a default button
            );
            if (result == 0) {
                if (name.getText() == null || name.getText().trim().length() == 0) {
                    UIUtils.showWarning("请填写角色名！");
                    return;
                }

                RoleInputArgs roleInputArgs = new RoleInputArgs();
                roleInputArgs.setId(role.getId());
                roleInputArgs.setName(name.getText());
                roleInputArgs.setCode(code.getText());
                roleInputArgs.setDescription(desc.getText());
                Set<Permission> perms = role.getPerms();
                List<String> permIds = new ArrayList<>();
                for (Permission p : perms) {
                    permIds.add(p.getId());
                }
                roleInputArgs.setPermIds(permIds);
                RoleDto dbRole = roleService.update(roleInputArgs);

                int selectedIndex = roleList.getSelectedIndex();
                roleModalList.removeElementAt(selectedIndex);
                roleModalList.add(selectedIndex, dbRole);
            }
        }
    }
}
